using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.Surface;
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;
using NAudio.Wave;
using NAudio.CoreAudioApi;
using AudioInterface;
using System.Collections;
using SurfaceApplication1.Classes;

/***************************************************************************
 * 
 * This is a test Windows surface application to play audio loops , hopefully
 * in time with the tempo.
 * 
 * Contact acobley@computing.dundee.ac.uk
 * ************************************************************************/

namespace SurfaceApplication1
{
    /// <summary>
    /// Interaction logic for SurfaceWindow1.xaml
    /// </summary>
    public partial class SurfaceWindow1 : SurfaceWindow
    {
        Stack toBePlayed = new Stack();
        
        static private double Tempo=125.0;
        static long Interval=(long)(60.0/Tempo*10000000.0);
        TimeSpan TS = new TimeSpan(Interval);
        System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
        int TempoCount = 1;
        sviExtension[] sviSample = new sviExtension[256];
        sviExtension sviCount = new sviExtension();
        //ScatterViewItem sviCountText = new ScatterViewItem();
        Image MetImg0 = new Image();
        Image MetImg1 = new Image();
        Image MetImg2 = new Image();
        Image MonkeyImg1 = new Image();
        Image MonkeyImg2 = new Image();

        static int NumSamples = 10;
        static int NumTypes = 4;
        Brush[] bkColours = new Brush[NumTypes];
        Hashtable PlayList = new Hashtable(NumSamples * NumTypes);
        /// <summary>
        /// Default constructor.
        /// </summary>
        public SurfaceWindow1()
        {
            
            
            InitializeComponent();
            // Add handlers for Application activation events
            AddActivationHandlers();

            NAudioInterface.SetupAudio(NumTypes*NumSamples);
            timer.Interval = TS;
            timer.Tick += new EventHandler(HandleTimer);
            timer.Start();

            ScatterView svMain = new ScatterView();
            String[] FileName = {"001.wav",
                                    "002.wav",
                                    "003.wav",
                                    "004.wav",
                                    "005.wav",
                                    "006.wav",
                                    "007.wav",
                                    "008.wav",
                                    "009.wav",
                                    "010.wav",
                                                              

            };
            String[] types = { "beats", "music", "perc","speach" };
            
            grid.Children.Add(svMain);


            bkColours[0] = Brushes.Goldenrod;
            bkColours[1] = Brushes.CornflowerBlue;
            bkColours[2] = Brushes.MistyRose;
            bkColours[3] = Brushes.Orchid;

            for (int offset = 0; offset < NumTypes*NumSamples; offset += NumSamples)
            {
                int nType = (int)(offset / NumSamples);
                String type = types[nType];
                for (int i = 0; i < NumSamples; i++)
                {
                    sviSample[i + offset] = new sviExtension();
                    sviSample[i + offset].Width = 100.0;
                    sviSample[i + offset].PreviewContactTapGesture += new ContactEventHandler(svi_PreviewContactTapGesture);
                    sviSample[i + offset].SizeChanged += new SizeChangedEventHandler(sviSample_SizeChanged);
                    sviSample[i + offset].Background = bkColours[nType];
                    sviSample[i + offset].setbkColour(bkColours[nType]);
                    sviSample[i + offset].BorderThickness = new Thickness(2.0);
                    sviSample[i + offset].Opacity = 0.8;
                    sviSample[i + offset].nType = nType;
                    svMain.Items.Add(sviSample[i + offset]);
                    if (nType == 0)
                    {
                        sviSample[i + offset].MonkeyImg1.Source = new BitmapImage(new Uri(@"C:\Samples\Monkey1.jpg"));
                        sviSample[i + offset].MonkeyImg2.Source = new BitmapImage(new Uri(@"C:\Samples\Monkey2.jpg"));
                    }
                    NAudioInterface.LoadSample(type, FileName[i], i + offset);
                    
                    double Volume = (float) 0.85;
                    String Content = "(" + type + ")" + FileName[i];
                    sviSample[i + offset].setName(Content);
                    sviSample[i + offset].Content = Content;
                    NAudioInterface.SetVolume(Content, (float)Volume);
                    NAudioInterface.Stop(i + offset);
                    
                }
            }
            sviCount.Background = Brushes.NavajoWhite;
            MetImg0.Source = new BitmapImage(new Uri(@"C:\Samples\Metronome.bmp"));
            MetImg1.Source = new BitmapImage(new Uri(@"C:\Samples\Metronome1A.bmp"));
            MetImg2.Source = new BitmapImage(new Uri(@"C:\Samples\Metronome2A.bmp"));

            //MonkeyImg1.Source = new BitmapImage(new Uri(@"C:\Samples\Monkey1.jpg"));
            //MonkeyImg2.Source = new BitmapImage(new Uri(@"C:\Samples\Monkey2.jpg"));
            Grid canvasGrid = new Grid();
            RowDefinition rowDef1 = new RowDefinition();
            RowDefinition rowDef2 = new RowDefinition();
            canvasGrid.RowDefinitions.Add(rowDef1);
            canvasGrid.RowDefinitions.Add(rowDef2);
            sviCount.Content = MetImg0;
            
           
            
            svMain.Items.Add(sviCount);
            sviCount.SizeChanged += new SizeChangedEventHandler(sviCount_SizeChanged);


        }

        void sviSample_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            sviExtension svi = (sviExtension)sender;
            double width = svi.Width;
            double Volume = (float)width / 100.0 *0.85;
            String content = svi.getName();
            NAudioInterface.SetVolume(content, (float)Volume);
        }

        void sviCount_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            ScatterViewItem svi = (ScatterViewItem)sender;
            double width = svi.Width;

           
        }

        void svi_PreviewContactTapGesture(object sender, ContactEventArgs e)
        {
            sviExtension svi = (sviExtension)sender;
            
            String content = svi.getName();
            if (svi.FontWeight.Equals(FontWeights.ExtraBold))
            {
                //Yes I know we are using the Bold property to tell if we are playing.  Naughty.
                // Tell the object we are no longer looping
                svi.FontWeight = FontWeights.Normal;
                svi.Background = svi.getbkColour();
                svi.Content = svi.getName();
                PlayList.Remove(svi);
            }
            else
            {
                //Ok we are playing
                //Add to playlist hashtable
                PlayList.Add(svi, true);
                svi.FontWeight = FontWeights.ExtraBold;
                svi.Background = Brushes.MediumSeaGreen;
            }
            toBePlayed.Push(content);
            
            
            
        }

        private void HandleTimer(Object sender, EventArgs args)
        {
        //some operations
        //if you want this event handler executed for just once
        // DispatcherTimer thisTimer = (DispatcherTimer)sender;
        // thisTimer.Stop();
            //sviCount.Content = TempoCount.ToString();
           
            IDictionaryEnumerator enumerator = PlayList.GetEnumerator();
            sviExtension svi;
            while (enumerator.MoveNext())
                {
                    svi = (sviExtension) enumerator.Key;
                    if ((TempoCount % 2) == 0){
                        svi.Background = Brushes.MediumSeaGreen;
                        if (svi.nType == 0)
                        {
                            svi.Content = svi.MonkeyImg1;
                        }
                    }else{
                        svi.Background = svi.getbkColour();
                        if (svi.nType == 0)
                        {
                            svi.Content = svi.MonkeyImg2;
                        }
                    }
               }
            if (TempoCount == 1)
            {
                sviCount.Content = MetImg0;
            }
            else
            {
                if ((TempoCount % 2) == 0)
                    sviCount.Content = MetImg2;
                else
                    sviCount.Content = MetImg1;
            }
            while ((toBePlayed.Count > 0) && (TempoCount==1))
            {
                String content = toBePlayed.Pop().ToString();
                
                if (NAudioInterface.isLooped(content) == false)
                {//Start looping
                    
                    NAudioInterface.Loop(content, true);
                    NAudioInterface.Play(content);
                }
                else
                {
                    
                    NAudioInterface.Loop(content, false);
                    NAudioInterface.Stop(content);
                }

            }
            TempoCount++;
            if (TempoCount > 4)
                TempoCount = 1;
        }


        /// <summary>
        /// Occurs when the window is about to close. 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);

            // Remove handlers for Application activation events
            RemoveActivationHandlers();
        }

        /// <summary>
        /// Adds handlers for Application activation events.
        /// </summary>
        private void AddActivationHandlers()
        {
            // Subscribe to surface application activation events
            ApplicationLauncher.ApplicationActivated += OnApplicationActivated;
            ApplicationLauncher.ApplicationPreviewed += OnApplicationPreviewed;
            ApplicationLauncher.ApplicationDeactivated += OnApplicationDeactivated;
        }

        /// <summary>
        /// Removes handlers for Application activation events.
        /// </summary>
        private void RemoveActivationHandlers()
        {
            // Unsubscribe from surface application activation events
            ApplicationLauncher.ApplicationActivated -= OnApplicationActivated;
            ApplicationLauncher.ApplicationPreviewed -= OnApplicationPreviewed;
            ApplicationLauncher.ApplicationDeactivated -= OnApplicationDeactivated;
        }

        /// <summary>
        /// This is called when application has been activated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationActivated(object sender, EventArgs e)
        {
            //TODO: enable audio, animations here
        }

        /// <summary>
        /// This is called when application is in preview mode.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationPreviewed(object sender, EventArgs e)
        {
            //TODO: Disable audio here if it is enabled

            //TODO: optionally enable animations here
        }

        /// <summary>
        ///  This is called when application has been deactivated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationDeactivated(object sender, EventArgs e)
        {
            //TODO: disable audio, animations here
        }

      
    }
}